package com.qdd.freight.handler.impl;

import com.qdd.freight.anno.Mode;
import com.qdd.freight.entity.Datas;
import com.qdd.freight.handler.AbstractDeliveryHandler;
import com.qdd.freight.pojo.Delivery;
import com.qdd.freight.pojo.GoodsShip;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Map;

/**
 * 京东快递
 *
 * @ClassName DBHandler
 * @Description TODO
 * @Author yanpeihao
 * @Date 2019/12/6 22:50
 * @Version 3.3
 **/

@Component
@Mode("8")
public class JDDelHandler extends AbstractDeliveryHandler {

    //快运方式名称
    private static final String YFMODE_NAME = "京东快递";
    //对应数据库的字段名
    private static final String TABLE_FIELD_NAME = "jdship_id";
    //对应数据库的字段名
    private static final String CONSTANT_FIELD_NAME = "jdshipId";

    @Override
    public String getShipFieldNameFromInstance() {
        return CONSTANT_FIELD_NAME;
    }

    /**
     * 关键属性值，避免使用时再查询数据库中的字段
     * (总重量1 = 箱规*单件重量,总重量2=箱规*单件体积/体重比(德邦,京东除以8000，顺丰除以9000))
     *
     * @Param boxVolume  箱体积
     * @Param shipId  运输方式id
     * @Param modeId 快递
     * @Param goodsId 商品id
     * @Param entId 仓库id
     * @Param singleVolume 单件体积
     * @Param quantity 采购数量
     * @Param boxWeight 箱重
     * @Param singleWeight 单重
     * @Param QTYRate 箱规
     */
    @Override
    public Datas realHandle(GoodsShip goodsShip, Integer shipId, Integer modeId, Integer goodsId,
                            Integer entId, Integer quantity, Integer company, String consignee,
                            Double boxVolume, Double singleVolume, Double boxWeight, Double singleWeight,
                            Integer QTYRate) throws Exception {
        //获取对象
        Delivery delivery = getDelivery(shipId);
        //获取可用的计价参数
        //1.2调用父类方法获取可用的计价方式参数
        Map<String, Object> params = getAvailableParams(delivery, shipId, consignee);
        //获取默认价格
        Integer startingWeight = (Integer) params.get("startingWeight");
        Double startingPrice = (Double) params.get("startingPrice");
        Integer headWeight = (Integer) params.get("headWeight");
        Double headPrice = (Double) params.get("headPrice");
        Integer extensionWeight = (Integer) params.get("extensionWeight");
        Double extensionPrice = (Double) params.get("extensionPrice");
        //定义价格变量
        Double price = 0.00;
        //判断计价方式
        switch (delivery.getType()) {
            //按重量计算判断
            case 0:
                //获取运价信息
                price = weighInWeight(quantity, singleWeight, singleVolume, startingWeight, startingPrice,
                        headWeight, headPrice, extensionWeight, extensionPrice);
                //按件数计算判断
            case 1:
                //获取运价信息
                price = byThePiece(quantity, startingWeight, startingPrice, headWeight, headPrice, extensionWeight, extensionPrice);
                break;
        }
        return packageDatas(modeId, goodsId, entId, quantity, price);
    }

    /**
     * 计重方式
     *
     * @return
     * @Param delivery
     */
    private Double weighInWeight(Integer quantity, Double singleWeight, Double singleVolume, Integer startingWeight,
                                 Double startingPrice, Integer headWeight, Double headPrice, Integer extensionWeight, Double extensionPrice) {
        if ((singleWeight * quantity) < startingWeight) {
            return startingPrice;
        } else {
            BigDecimal bQuantity = BigDecimal.valueOf(quantity);
            BigDecimal bSingleWeight = BigDecimal.valueOf(singleWeight);
            BigDecimal bSingleVolume = BigDecimal.valueOf(singleVolume);
            Double sumWeight = ((bSingleVolume.divide(new BigDecimal(8), 2, BigDecimal.ROUND_HALF_UP).compareTo(bSingleWeight) == 1)
                    ? bSingleVolume.divide(new BigDecimal(8), 2, BigDecimal.ROUND_HALF_UP) : bSingleWeight).multiply(bQuantity).doubleValue();
            return weightFreightRate(sumWeight, headWeight, headPrice, extensionWeight, extensionPrice);
        }

    }

    /**
     * 计件方式
     *
     * @return
     * @Param delivery 物流对象
     * @Param purchaseNum 采购数量
     */
    private Double byThePiece(Integer quantity, Integer startingWeight, Double startingPrice, Integer headWeight,
                              Double headPrice, Integer extensionWeight, Double extensionPrice) {
        if (quantity < startingWeight) {
            return startingPrice;
        } else {
            return startingPriceCalculation(quantity, headWeight, headPrice, extensionWeight, extensionPrice);
        }
    }
}